import { TrackOpTypes, computed, ref } from 'vue'
var plugin = requirePlugin('WechatSI')
const base = require('../../static/js/base64js.js')
require('../../static/js/enc-base64-min')
const CryptoJS = require('../../static/js/hmac-sha256')
import { splitSentences } from 'uniapp-sentence-splitter'
const fastXml = require('../../static/js/fast-xml-parser.min.js')
import { BASE_URL } from '@/config'
const handlerInterval = ref()
const handlerIntervalComment = ref()
let music = uni.createInnerAudioContext()
let socketTask = null
let socketTaskComment = null
let socketTaskMp3 = null
let timer = null
let pathArray: any = []
const APPID = '374c079e'
const API_SECRET = 'ZDU1NmFkZWViNzc1NWE0ZGY1OTlkMTQw'
const API_KEY = 'bdbe2313becb7547ef7650ebfc1d294c'
export const useWebsocket = () => {
  // 生成握手参数
  const getWebSocketUrl = () => {
    return new Promise((resolve, reject) => {
      // 请求地址根据语种不同变化
      var url = 'wss://iat-api.xfyun.cn/v2/iat'
      var host = 'iat-api.xfyun.cn'
      var apiKey = API_KEY
      var apiSecret = API_SECRET
      var date = new Date().toGMTString()
      var algorithm = 'hmac-sha256'
      var headers = 'host date request-line'
      var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`
      var signatureSha = CryptoJS.default.HmacSHA256(signatureOrigin, apiSecret)
      var signature = CryptoJS.default.enc.Base64.stringify(signatureSha)
      var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
      var authorization = base.Base64.btoa(authorizationOrigin)
      url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
      resolve(url)
    })
  }
  // 生成握手参数(评分)
  const getWebSocketUrlComment = () => {
    // 请求地址根据语种不同变化
    var url = 'wss://ise-api.xfyun.cn/v2/open-ise'
    var host = 'ise-api.xfyun.cn'
    var apiKey = API_KEY
    var apiSecret = API_SECRET
    var date = new Date().toGMTString()
    var algorithm = 'hmac-sha256'
    var headers = 'host date request-line'
    var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/open-ise HTTP/1.1`
    var signatureSha = CryptoJS.default.HmacSHA256(signatureOrigin, apiSecret)
    var signature = CryptoJS.default.enc.Base64.stringify(signatureSha)
    var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
    var authorization = base.Base64.btoa(authorizationOrigin)
    url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
    return url
  }
  // 文字转音频
  const getWebSocketUrlMp3 = () => {
    return new Promise((resolve, reject) => {
      var url = 'wss://tts-api.xfyun.cn/v2/tts'
      var host = 'tts-api.xfyun.cn'
      var apiKey = API_KEY
      var apiSecret = API_SECRET
      var date = new Date().toGMTString()
      var algorithm = 'hmac-sha256'
      var headers = 'host date request-line'
      var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`
      var signatureSha = CryptoJS.default.HmacSHA256(signatureOrigin, apiSecret)
      var signature = CryptoJS.default.enc.Base64.stringify(signatureSha)
      var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
      var authorization = base.Base64.btoa(authorizationOrigin)
      url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
      resolve(url)
    })
  }
  // 生成小程序在线预览地址
  const handleGeneratePath = (res, type = 'normal') => {
    return new Promise((resolve, reject) => {
      let newArr = []
      console.log(res, 'resnewUrl')
      res.map((item, index) => {
        const arrayBuffer = wx.base64ToArrayBuffer(item)
        const newBuffer = new Uint8Array(arrayBuffer)
        newArr.push(...newBuffer)
      })
      let uint8Array = new Uint8Array(newArr)
      const newUrl = wx.createBufferURL(uint8Array.buffer)
      console.log(newUrl, 'newUrlnewUrlnewUrl')
      if (type == 'normal') {
        resolve(newUrl)
      } else {
        resolve({
          uint8Array: uint8Array,
          url: newUrl,
        })
      }
    })
  }
  // 批量生成小程序预览地址
  const handleBatchGeneratePath = (res) => {
    return new Promise((resolve, reject) => {
      let newArr = []
      res.map((item, index) => {
        const arrayBuffer = wx.base64ToArrayBuffer(item)
        const newBuffer = new Uint8Array(arrayBuffer)
        newArr.push(...newBuffer)
      })
      let uint8Array = new Uint8Array(newArr)
      const newUrl = wx.createBufferURL(uint8Array.buffer)
      resolve(newUrl)
    })
  }
  // 连续播放多个音频
  const handlePlayAll = () => {
    const testFun = async function (i) {
      if (i >= pathArray.length) {
        return
      } else {
        console.log('211221')
        await handlePlayVideo(pathArray[i])
      }
      i++
      testFun(i)
      return
    }
    testFun(0)
  }
  // 播放音頻
  const handleClickVideo = (filename: string) => {
    let platform = uni.getSystemInfoSync().platform
    // switch (platform) {
    //   case 'android':
    //     console.log('运行Android上')
    //     music.destroy()
    //     music = uni.createInnerAudioContext()
    //     break
    //   case 'ios':
    //     console.log('运行iOS上')
    //     music.destroy()
    //     music = uni.createInnerAudioContext()
    //     break
    //   default:
    //     console.log('运行在开发者工具上')
    //     music.destroy()
    //     music = uni.createInnerAudioContext()
    //     break
    // }
    music.destroy()
    music = uni.createInnerAudioContext()
    return new Promise((resolve, reject) => {
      if (music.paused || platform == 'android') {
        handlePlayVideo(filename).then(() => {
          resolve(true)
        })
      } else {
        handlePauseVideo(filename)
      }
    })
  }
  // 开始播放
  const handlePlayVideo = (filename: string) => {
    return new Promise((resolve, reject) => {
      music.src = filename
      // console.log(filename,"filenamefilenamefilename")
      music.play() //执行播放
      music.onEnded(() => {
        //播放结束
        music = uni.createInnerAudioContext()
        resolve(true)
      })
    })
  }
  // 清除播放
  const handleClearVideo = () => {
    music.pause()
    music.stop()
    // music = uni.createInnerAudioContext()
  }
  // 暂停播放
  const handlePauseVideo = (filename: string) => {
    music.pause()
  }
  // 停止播放
  const handleCloseVideo = () => {
    music.stop()
  }
  // 连接websocket
  const connectWebSocket = () => {
    let str = ''
    return new Promise((resolve, reject) => {
      getWebSocketUrl().then((url) => {
        socketTask = uni.connectSocket({
          url: encodeURI(url),
          success: () => {},
          complete: () => {},
        })
        console.log('将汇聚点击', socketTask)
        socketTask.onOpen(function (res) {
          console.log('WebSocket连接已打开！')
        })
        socketTask.onError(function (res) {
          console.log('WebSocket连接打开失败，请检查11111！')
        })
        socketTask.onMessage(function (res) {
          console.log('收到服务器内容内容', res.data)
          if (res.data && JSON.parse(res.data).code == 0) {
            let jsonData = JSON.parse(res.data)
            str += result(res.data)
            console.log(
              jsonData.data.status,
              'jsonData.data.statusjsonData.data.status'
            )
            if (jsonData.data.status == 2) {
              resolve(str)
              socketTask.close()
            }
          } else {
            console.log('收到服务器内容失败失败失败失败')
          }
        })
        socketTask.onClose(function (res) {
          console.log(res.reason, 'eeeeeeeeee')
        })
      })
    })
  }
  // 连接websocket(评分功能)
  const connectWebSocketComment = (text: string) => {
    return new Promise((resolve, reject) => {
      const websocketUrl = getWebSocketUrlComment()
      socketTaskComment = uni.connectSocket({
        url: encodeURI(websocketUrl),
        success: () => {},
        complete: () => {},
      })
      socketTaskComment.onOpen(function (res) {
        console.log('WebSocket连接成功，请检查2222！')
        let params = {
          common: {
            app_id: APPID,
          },
          business: {
            category: 'read_sentence', // read_syllable/单字朗读，汉语专有 read_word/词语朗读 ，read_chapter/篇章朗读 read_sentence/句子朗读 https://www.xfyun.cn/doc/Ise/IseAPI.html#%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8%E6%B5%81%E7%A8%8B
            rstcd: 'utf8',
            group: 'pupil',
            sub: 'ise',
            tte: 'utf-8',
            cmd: 'ssb',
            auf: 'audio/L16;rate=16000',
            ent: 'en_vip',
            aus: 1,
            grade: 'middle',
            aue: 'raw',
            text: '\uFEFF' + text,
          },
          data: {
            status: 0,
          },
        }
        socketTaskComment.send({
          data: JSON.stringify(params),
        })
      })
      socketTaskComment.onError(function (res) {
        console.log('WebSocket连接打开失败，请检查2222！')
      })
      socketTaskComment.onMessage(function (res) {
        console.log('收到服务器内容評分功能：' + res.data)
        let data = JSON.parse(res.data)

        if (data.data && data.data.status == 2) {
          if (data.code == 0) {
            console.log('出评分结果', res.data)
            resolve(renderResult(res.data))
            socketTaskComment.close()
          } else {
            //异常
            console.log('评分异常评分异常评分异常')
            reject()
          }
        }
      })
      socketTaskComment.onClose(function (res) {
        console.log(res, 'rrrrrrr')
        // reject()
      })
    })
  }
  // 关闭websocket
  const closeWebSocket = () => {
    console.log('关闭websocket')
    // uni.closeSocket()
    // uni.onSocketClose(function (res) {
    //   console.log('全部WebSocket已关闭！')
    // })
    socketTaskComment.close({
      success: () => {
        console.log('关闭socketTaskCommentwebsocket成功')
      },
      fail: () => {
        console.log('关闭socketTaskCommentwebsocket失败')
      },
    })
    socketTaskComment.onClose(function (res) {
      console.log(res, '顶顶顶顶顶')
    })
    socketTask.close({
      success: () => {
        console.log('关闭socketTaskwebsocket成功')
      },
      fail: () => {
        console.log('关闭socketTaskwebsocket失败')
      },
    })
    console.log(
      '关闭websocket关闭websocket关闭websocket关闭websocket关闭websocket关闭websocket'
    )
  }
  // 文字转语音
  const connectWebSocketMp3 = (str: string, type: string) => {
    return new Promise((resolve, reject) => {
      let resultArray: any = []
      let resultArrayAll: any = []
      getWebSocketUrlMp3().then((url) => {
        socketTaskMp3 = uni.connectSocket({
          url: encodeURI(url),
          success: () => {},
          complete: () => {},
        })
        socketTaskMp3.onOpen(function (res) {
          let params = {
            common: {
              app_id: APPID,
            },
            business: {
              aue: 'lame',
              auf: 'audio/L16;rate=16000',
              vcn:
                type == 'Chinese'
                  ? 'x4_enus_catherine_profnews'
                  : 'x4_enus_ryan_assist',
              speed: 50,
              volume: 50,
              pitch: 50,
              bgs: 0,
              tte: 'UTF8',
            },
            data: {
              status: 2,
              text: encodeText(str, false),
            },
          }
          socketTaskMp3.send({
            data: JSON.stringify(params),
          })
        })
        socketTaskMp3.onError(function (res) {
          console.log('生成Mp3的WebSocket连接打开失败，请检查！')
        })
        socketTaskMp3.onMessage(async function (res) {
          let jsonData = JSON.parse(res.data)
          // 合成失败
          if (jsonData.code !== 0) {
            uni.showToast({
              title: '合成失败',
              icon: 'none',
            })
            return
          }
          resultArrayAll.push(jsonData.data.audio)
          // resultArray.push(jsonData.data.audio)
          // if(resultArray.length >= 100){
          //   let path = await handleBatchGeneratePath(resultArray.splice(0,100))
          //   pathArray.push(path)
          // }
          if (jsonData.code === 0 && jsonData.data.status === 2) {
            // let path = await handleBatchGeneratePath(resultArray.splice(0,resultArray.length))
            // pathArray.push(path)
            // handlePlayAll()
            resolve(resultArrayAll)
            socketTaskMp3 = uni.closeSocket()
          }
        })
      })
    })
  }
  // Mp3
  const webSocketSendMp3 = (str: string, type: string) => {
    return new Promise((resolve, reject) => {
      connectWebSocketMp3(str, type).then((res) => {
        resolve(res)
      })
    })
  }
  const toBase64 = (buffer: any, type) => {
    var binary = ''
    var bytes = new Uint8Array(buffer)
    var len = bytes.byteLength
    for (var i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i])
    }
    if (type == 'mp3') {
      return base.Base64.btoa(binary)
    } else {
      return base.Base64.btoa(binary)
    }
  }
  const encodeText = (text, type) => {
    if (type === 'unicode') {
      let buf = new ArrayBuffer(text.length * 4)
      let bufView = new Uint16Array(buf)
      for (let i = 0, strlen = text.length; i < strlen; i++) {
        bufView[i] = text.charCodeAt(i)
      }
      let binary = ''
      let bytes = new Uint8Array(buf)
      let len = bytes.byteLength
      for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i])
      }
      return window.btoa(binary)
    } else {
      return base.Base64.encode(text)
    }
  }
  // 分数转换
  const renderResult = (resultData: string) => {
    let jsonData = JSON.parse(resultData)
    console.log(jsonData)
    if (jsonData.data.data) {
      let data = base.Base64.atob(jsonData.data.data)
      let grade = fastXml.default.parse(data, {
        attributeNamePrefix: '',
        ignoreAttributes: false,
      })
      const readSentence =
        grade?.xml_result?.read_sentence?.rec_paper?.read_chapter
      console.log(readSentence)
      if (readSentence == undefined) {
        console.log(`结果解析xml失败了`)
      }
      return readSentence
    }
    if (jsonData.code === 0 && jsonData.data.status === 2) {
      socketTaskComment.close()
    }
    if (jsonData.code !== 0) {
      socketTaskComment.close()
    }
  }
  const result = (resultData: string) => {
    // 识别结束
    let jsonData = JSON.parse(resultData)
    if (jsonData.data && jsonData.data.result) {
      let data = jsonData.data.result
      let str = ''
      let ws = data.ws
      for (let i = 0; i < ws.length; i++) {
        str = str + ws[i].cw[0].w
      }
      if (data.pgs) {
        return str
      } else {
        return str
      }
    }
    if (jsonData.code === 0 && jsonData.data.status === 2) {
      // socketTask.onClose()
      uni.onSocketClose(function (res) {
        console.log('WebSocket 已关闭！')
      })
    }
    if (jsonData.code !== 0) {
      // socketTask.onClose()
      uni.onSocketClose(function (res) {
        console.log('WebSocket 已关闭！')
      })
    }
  }
  const base64toJson = (base64: string) => {
    const base64EncodedJson = base64
    // 解码base64字符串
    const base64Decoded = decodeURIComponent(
      escape(base.Base64.atob(base64EncodedJson))
    )
    // console.log(base64Decoded,"base64Decoded")
    // 解析JSON字符串为对象
    // let utf8String = decodeURIComponent(
    //   Array.from(
    //     base64Decoded,
    //     (char) => '%' + ('00' + char.charCodeAt(0).toString(16)).slice(-2)
    //   ).join('')
    // )
    // const jsonObject = JSON.parse(base64Decoded)
    return base64Decoded
  }
  //中文转语音
  const textToSpeech = (content) => {
    return new Promise((resolve, reject) => {
      plugin.textToSpeech({
        lang: 'en_US',
        tts: true,
        content: content,
        success: function (res) {
          if (res.retcode == 0) {
            resolve(res.filename)
          } else {
            reject()
          }
        },
        fail: function (res) {
          console.log('fail tts', res)
        },
      })
    })
  }
  //英文转中文
  const textTranslate = (content: string) => {
    return new Promise((resolve, reject) => {
      plugin.translate({
        lfrom: 'en_US',
        lto: 'zh_CN',
        tts: true,
        content: content,
        success: function (res) {
          if (res.retcode == 0) {
            console.log(`zzfs 222222`)
            resolve(res.result)
          } else {
            reject()
          }
        },
        fail: function (res) {
          console.log('fail tts', res)
          reject()
        },
      })
    })
  }
  //中文转英文
  const textTranslateZh = (content: string) => {
    return new Promise((resolve, reject) => {
      plugin.translate({
        lfrom: 'zh_CN',
        lto: 'en_US',
        tts: true,
        content: content,
        success: function (res) {
          if (res.retcode == 0) {
            console.log(`zzfs1111 `)
            resolve(res.result)
          } else {
            reject()
          }
        },
        fail: function (res) {
          console.log('fail tts', res)
          reject()
        },
      })
    })
  }
  const webSocketSendComment = (
    frameBuffer: any,
    textContent: String,
    isLastFrame,
    currentNum
  ) => {
    return new Promise((resolve, reject) => {
      if (socketTaskComment.readyState == socketTaskComment.OPEN) {
        socketTaskComment.send({
          data: JSON.stringify({
            business: {
              aue: 'raw',
              cmd: 'auw',
              aus: isLastFrame ? 4 : 2,
            },
            data: {
              status: isLastFrame ? 2 : 1,
              data_type: 1,
              data: toBase64(frameBuffer),
            },
          }),
        })
      }
      if (currentNum == 'end') {
        socketTaskComment.send({
          data: JSON.stringify({
            business: {
              aue: 'raw',
              cmd: 'auw',
              aus: isLastFrame ? 4 : 2,
            },
            data: {
              status: isLastFrame ? 2 : 1,
              data_type: 1,
              data: toBase64(frameBuffer),
            },
          }),
        })
        if (isLastFrame) {
          resolve('success')
        }
      }
    })
  }
  // 流式返回数据
  const sendMessage = (data: any) => {
    return new Promise((resolve, reject) => {
      const requestTask = uni.request({
        url: `${BASE_URL}/enteacher/aichat`,
        timeout: 15000,
        responseType: 'text',
        method: 'POST',
        enableChunked: true,
        data: data,
        success: (response) => {
          console.log(response)
        },
        fail: (error) => {},
      })
      requestTask.onHeadersReceived(function (res) {
        console.log(456)
        console.log(res.header)
      })

      // 这里监听消息
      requestTask.onChunkReceived(function (res) {
        // console.log(res,"rere")
        const uint8Array = new Uint8Array(res.data)
        let text = String.fromCharCode.apply(null, uint8Array)

        let object = {}
        if (text.indexOf(':HTTP_STATUS/200') != -1) {
          let obj = text.split('```json')[1].split('```')[0]
          let newStr = obj.replace(/\\n/g, '').replace(/\\/g, '')
          let newData = JSON.parse(newStr)
          resolve(newData)
        }
      })
    })
  }
  const webSocketSend = (frameBuffer: any, isLastFrame: boolean) => {
    return new Promise((resolve, reject) => {
      if (socketTask.readyState == socketTask.OPEN) {
        let params = {
          common: {
            app_id: APPID,
          },
          business: {
            language: 'en_us', //小语种可在控制台--语音听写（流式）--方言/语种处添加试用
            domain: 'iat',
            accent: 'mandarin', //中文方言可在控制台--语音听写（流式）--方言/语种处添加试用
            vad_eos: 30000,
            dwa: 'wpgs', //为使该功能生效，需到控制台开通动态修正功能（该功能免费）
          },
          data: {
            status: isLastFrame ? 2 : 1,
            format: 'audio/L16;rate=16000',
            encoding: 'raw',
            audio: toBase64(frameBuffer),
          },
        }
        socketTask.send({
          data: JSON.stringify(params),
        })
      }
    })
  }
  const splitText = (text) => {
    return splitSentences(text)
  }
  //防抖
  const handleDebounce = (fn, time) => {
    clearTimeout(timer)
    timer = setTimeout(() => {
      fn()
    }, time)
  }
  // pcm转wav音频
  const encodeWAV = (samples, numChannels, sampleRate) => {
    var buffer = new ArrayBuffer(44 + samples.byteLength)
    var view = new DataView(buffer)
    /* RIFF identifier */
    writeString(view, 0, 'RIFF')
    /* RIFF chunk length */
    view.setUint32(4, 36 + samples.byteLength, true)
    /* RIFF type */
    writeString(view, 8, 'WAVE')
    /* format chunk identifier */
    writeString(view, 12, 'fmt ')
    /* format chunk length */
    view.setUint32(16, 16, true)
    /* sample format (raw) */
    view.setUint16(20, 1, true)
    /* channel count */
    view.setUint16(22, numChannels, true)
    /* sample rate */
    view.setUint32(24, sampleRate, true)
    /* byte rate (sample rate * block align) */
    view.setUint32(28, sampleRate * 4, true)
    /* block align (channel count * bytes per sample) */
    view.setUint16(32, numChannels * 2, true)
    /* bits per sample */
    view.setUint16(34, 16, true)
    /* data chunk identifier */
    writeString(view, 36, 'data')
    /* data chunk length */
    view.setUint32(40, samples.byteLength, true)

    copyBytes(view, 44, samples)

    return view
  }
  const copyBytes = (output, offset, input) => {
    const dataView = new DataView(input)
    for (var i = 0; i < input.byteLength; i++, offset++) {
      output.setInt8(offset, dataView.getInt8(i))
    }
  }
  const writeString = (view, offset, string) => {
    for (var i = 0; i < string.length; i++) {
      view.setUint8(offset + i, string.charCodeAt(i))
    }
  }

  return {
    getWebSocketUrl,
    getWebSocketUrlComment,
    handleClickVideo,
    handlePauseVideo,
    handlePlayVideo,
    connectWebSocket,
    connectWebSocketComment,
    connectWebSocketMp3,
    toBase64,
    textTranslate,
    textTranslateZh,
    base64toJson,
    webSocketSend,
    handleCloseVideo,
    webSocketSendComment,
    webSocketSendMp3,
    textToSpeech,
    sendMessage,
    APPID,
    API_SECRET,
    API_KEY,
    splitText,
    encodeText,
    closeWebSocket,
    handleDebounce,
    handleGeneratePath,
    encodeWAV,
    copyBytes,
    writeString,
    handleClearVideo,
  }
}
